package lc.activiti.contract.service.impl;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.task.Task;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import lc.activiti.common.ActivitiProcessType;
import lc.activiti.common.BrowseAppStatus;
import lc.activiti.common.ContractProcessStatus;
import lc.activiti.common.ContractStatus;
import lc.activiti.common.GuidUtils;
import lc.activiti.contract.dao.ICommonQueryDao;
import lc.activiti.contract.dao.base.IBrowsePermissionDao;
import lc.activiti.contract.dao.base.IContractDao;
import lc.activiti.contract.dao.base.IDepartmentBaseDao;
import lc.activiti.contract.dao.base.IUserDao;
import lc.activiti.contract.entity.BrowsePermission;
import lc.activiti.contract.entity.Contract;
import lc.activiti.contract.model.EmailModel;
import lc.activiti.contract.service.ICommonService;
import lc.activiti.contract.service.IContractApprovalService;
import lc.activiti.contract.service.IEmailTaskService;
import lc.activiti.model.SubApprovalModel;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class ContractApprovalServiceImpl implements IContractApprovalService {

	@Autowired
	private ProcessEngine processEngine;
	private String processDefinitKey = "contractApprovalProcess";
	@Autowired
	private IContractDao contractDao;
	@Autowired
	private IDepartmentBaseDao departmentDao;
	@Autowired
	private ICommonQueryDao commonQueryDao;

	@Autowired
	private IUserDao userDao;

	@Autowired
	private ICommonService commonService;

	@Autowired
	private IEmailTaskService emailTaskService;

	/**
	 * 【合同审批流程】 提交合同
	 */
	@Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
	@Override
	public void submitApproval(SubApprovalModel subModel) {
		if (null == subModel) {
			throw new RuntimeException("提交信息不能为空！");
		}
		SubApprovalModel nextApprovalUser = commonService.getNextApprovalUser(subModel.getBusinessId(),
				subModel.getDepartmentId());
		Contract contract = contractDao.selectByPrimaryKey(subModel.getBusinessId());
		if (!contract.getStatus().equals(ContractStatus.NewCreate.getStatus())
				&& !contract.getStatus().equals(ContractStatus.Reject.getStatus())) {
			throw new RuntimeException("合同已提交!不能重复提交!业务Id:" + subModel.getBusinessId());
		}

		String businessId = subModel.getBusinessId();

		subModel = commonService.additionalUsers(subModel);

		// 启动申请流程
		if (!contract.getStatus().equals(ContractStatus.Reject.getStatus())) {
			Map<String, Object> vaiarbles = new HashMap<>();
			vaiarbles.put("subApprovalModel", subModel);
			vaiarbles.put("processTag", ContractProcessStatus.Submit.getStatus());
			vaiarbles.put("nextApprovalUser", nextApprovalUser);
			processEngine.getRuntimeService().startProcessInstanceByKey(processDefinitKey, businessId, vaiarbles);
		} else {
			// 驳回再提交
			Map<String, Object> vaiarbles = new HashMap<>();
			vaiarbles.put("subApprovalModel", subModel);
			vaiarbles.put("processTag", ContractProcessStatus.RejectSubmit.getStatus());
			vaiarbles.put("nextApprovalUser", nextApprovalUser);
			// 驳回再提交
			Task task = processEngine.getTaskService().createTaskQuery()
					.processInstanceBusinessKey(subModel.getBusinessId()).singleResult();
			processEngine.getTaskService().setAssignee(task.getId(), subModel.getUserId());
			processEngine.getTaskService().complete(task.getId(), vaiarbles);
		}
		UpdateContractStatus(subModel, ContractStatus.Apploy.getStatus());

		List<SubApprovalModel> nextApprovalList = new ArrayList<>();
		nextApprovalList.add(nextApprovalUser);

		String emailContent = String.format("您有一个合同【待审批】,合同编号:【%s】 合同名称:【%s】", contract.getContractCode(),
				contract.getContractName());
		EmailModel eModel = new EmailModel();
		eModel.setSubject("【合同申请】");
		eModel.setActivitiProcessType(ActivitiProcessType.ContactApprovalProcess);
		eModel.setBussinesOperatorType(ContractProcessStatus.Submit);
		eModel.setCurrentUsers(subModel);
		eModel.setIsSendSubmit(false);
		eModel.setContent(emailContent);
		eModel.setNextApprovalList(nextApprovalList);

		emailTaskService.sendEmail(eModel);
	}

	private Contract UpdateContractStatus(SubApprovalModel subModel, Short status) {
		Contract contract = contractDao.selectByPrimaryKey(subModel.getBusinessId());
		if (null == contract) {
			throw new RuntimeException("不存在此合同" + subModel.getBusinessId());
		}
		contract.setStatus(status);
		contractDao.updateByPrimaryKey(contract);
		return contract;
	}

	/**
	 * 【合同审批流程】 合同 审批通过
	 */
	@Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
	@Override
	public void approvalSuccess(SubApprovalModel subApprovalModel) {
		if (null == subApprovalModel || StringUtils.isBlank(subApprovalModel.getBusinessId())) {
			throw new RuntimeException("提交信息为空！或者业务Id为空");
		}
		Contract contract = contractDao.selectByPrimaryKey(subApprovalModel.getBusinessId());
		if (!contract.getStatus().equals(ContractStatus.Apploy.getStatus())) {
			throw new RuntimeException("合同不是已提交状态!不能提交审批!业务Id:" + subApprovalModel.getBusinessId());
		}
		if (contract.getStatus().equals(ContractStatus.Approvaled.getStatus())) {
			throw new RuntimeException("合同已审批!不能重复提交!业务Id:" + subApprovalModel.getBusinessId());
		}
		subApprovalModel = commonService.additionalUsers(subApprovalModel);
		Task task = processEngine.getTaskService().createTaskQuery()
				.processInstanceBusinessKey(subApprovalModel.getBusinessId()).singleResult();
		Map<String, Object> currVariables = processEngine.getTaskService().getVariables(task.getId());
		SubApprovalModel currentApprovalUser = (SubApprovalModel) currVariables.get("nextApprovalUser");

		List<SubApprovalModel> nextAuditUserList = commonService
				.getNextAuditUserList(currentApprovalUser.getBusinessId(), currentApprovalUser.getDepartmentId());
		SubApprovalModel subModel = (SubApprovalModel) processEngine.getTaskService().getVariable(task.getId(),
				"subApprovalModel");
		
		Map<String, Object> vaiables = new HashMap<>();
		vaiables.put("isApproval", true);
		vaiables.put("processTag", ContractProcessStatus.ApprovalSuccess.getStatus());
		vaiables.put("auditUsers", nextAuditUserList);
		vaiables.put("currentUser", subApprovalModel);
		processEngine.getTaskService().setVariableLocal(task.getId(), "approvalSuccessUserInfo", vaiables);
	
		processEngine.getTaskService().complete(task.getId(), vaiables);
		UpdateContractStatus(subApprovalModel, ContractStatus.Approvaled.getStatus());

		

		String subject = "【合同申请】";
		String subjectAudit="【合同申请】";
		String emailContent = String.format("您有一个合同【待审核】,合同编号:【%s】 合同名称:【%s】", contract.getContractCode(),
				contract.getContractName());
		String subEmailContent = String.format("您的合同编号:【%s】 合同名称:【%s】 通过审批!", contract.getContractCode(),
				contract.getContractName());
		EmailModel eModel = new EmailModel();
		eModel.setSubject(subjectAudit);
		eModel.setActivitiProcessType(ActivitiProcessType.ContactApprovalProcess);
		eModel.setBussinesOperatorType(ContractProcessStatus.ApprovalSuccess);
		eModel.setCurrentUsers(subModel);
		eModel.setIsSendSubmit(true);
		eModel.setContent(emailContent);
		eModel.setSubmitSubject(subject);
		eModel.setSubContent(subEmailContent);
		eModel.setNextApprovalList(nextAuditUserList);

		emailTaskService.sendEmail(eModel);

	}

	/**
	 * 【合同审批流程】 审批驳回
	 */
	@Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
	@Override
	public void rejectApproval(SubApprovalModel subApprovalModel) {
		if (null == subApprovalModel || StringUtils.isBlank(subApprovalModel.getBusinessId())) {
			throw new RuntimeException("提交信息为空！或者业务Id为空");
		}
		Contract contract = contractDao.selectByPrimaryKey(subApprovalModel.getBusinessId());
		if (contract.getStatus().equals(ContractStatus.Reject.getStatus())) {
			throw new RuntimeException("合同已驳回!不能重复提交!业务Id:" + subApprovalModel.getBusinessId());
		}
		subApprovalModel = commonService.additionalUsers(subApprovalModel);
		Task task = processEngine.getTaskService().createTaskQuery()
				.processInstanceBusinessKey(subApprovalModel.getBusinessId()).singleResult();
		// SubApprovalModel
		// currentApprovalUser=(SubApprovalModel)task.getProcessVariables().get("nextApprovalUser");

		// SubApprovalModel
		// nextApprovalUser=getNextAuditUser(currentApprovalUser.getBusinessId(),
		// currentApprovalUser.getDepartmentId());
		// task.setName("审批驳回合同");
		
		SubApprovalModel subModel = (SubApprovalModel) processEngine.getTaskService().getVariable(task.getId(),
				"subApprovalModel");

		Map<String, Object> vaiables = new HashMap<>();
		vaiables.put("isApproval", false);
		vaiables.put("processTag", ContractProcessStatus.ApprovalReject.getStatus());
		vaiables.put("currentUser", subApprovalModel);
		processEngine.getTaskService().setVariableLocal(task.getId(), "approvalRejectUserInfo", subApprovalModel);

		processEngine.getTaskService().addComment(task.getId(), task.getProcessInstanceId(),
				subApprovalModel.getReason());
		processEngine.getTaskService().complete(task.getId(), vaiables);
		UpdateContractStatus(subApprovalModel, ContractStatus.Reject.getStatus());

		
		String subject = "【合同申请】";
		String subEmailContent = String.format("您的合同被驳回! 合同编号:【%s】 合同名称:【%s】 ", contract.getContractCode(),
				contract.getContractName());
		EmailModel eModel = new EmailModel();
		//eModel.setSubject(subject);
		eModel.setActivitiProcessType(ActivitiProcessType.ContactApprovalProcess);
		eModel.setBussinesOperatorType(ContractProcessStatus.ApprovalSuccess);
		eModel.setCurrentUsers(subModel);
		eModel.setIsSendSubmit(true);
		//eModel.setContent(subEmailContent);
		eModel.setSubmitSubject(subject);
		eModel.setSubContent(subEmailContent);
		emailTaskService.sendEmail(eModel);
	}

	@Autowired
	private IBrowsePermissionDao browsePermissionDao;
	private final static String browseContractProcessInstanceKey = "contractBrowseProcess";

	/**
	 * 【查看申请流程】 审批驳回
	 */
	@Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
	@Override
	public void browseApprovalReject(SubApprovalModel appModel) {
		try {
			ValidData(appModel);

			BrowsePermission browsePermission = browsePermissionDao.selectByPrimaryKey(appModel.getBusinessId());
			if (null == browsePermission) {
				throw new RuntimeException("预览申请信息为空!");
			}
			if (!browsePermission.getStatus().equals(BrowseAppStatus.Apploy.getStatus())) {
				throw new RuntimeException("预览申请非提交状态不能提交!");
			}

			Map<String, Object> vaiarbles = new HashMap<String, Object>();
			vaiarbles.put("isApproval", false);
			vaiarbles.put("processTag", ContractProcessStatus.ApprovalReject.getStatus());
			Task task = processEngine.getTaskService().createTaskQuery()
					.processInstanceBusinessKey(appModel.getBusinessId()).singleResult();
			
			SubApprovalModel subModel = (SubApprovalModel) processEngine.getTaskService().getVariable(task.getId(),
					"subApprovalModel");
			
			processEngine.getTaskService().setVariableLocal(task.getId(), "browseApprovalRejectUserInfo", appModel);
			processEngine.getTaskService().addComment(task.getId(), task.getProcessInstanceId(), appModel.getReason());
			processEngine.getTaskService().complete(task.getId(), vaiarbles);

			updateContractBrowseStatus(browsePermission, appModel, BrowseAppStatus.Reject.getStatus());
			
			Contract contract=commonQueryDao.getContractByBrowsePermissionId(appModel.getBusinessId());
			String subject = "【合同查看申请】";
			String subEmailContent = String.format("您的合同查看申请被驳回! 合同编号:【%s】 合同名称:【%s】 ", contract.getContractCode(),
					contract.getContractName());
			EmailModel eModel = new EmailModel();
			//eModel.setSubject(subject);
			eModel.setActivitiProcessType(ActivitiProcessType.ContactBrowseApprovalProcess);
			eModel.setBussinesOperatorType(ContractProcessStatus.ApprovalReject);
			eModel.setCurrentUsers(subModel);
			eModel.setIsSendSubmit(true);
			//eModel.setContent(subEmailContent);
			eModel.setSubmitSubject(subject);
			eModel.setSubContent(subEmailContent);
			emailTaskService.sendEmail(eModel);
		} catch (Exception e) {
			throw e;
		}
	}

	/**
	 * 【查看申请流程】 审批通过
	 */
	@Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
	@Override
	public void browseApprovalSuccess(SubApprovalModel appModel) {
		try {
			ValidData(appModel);

			BrowsePermission browsePermission = browsePermissionDao.selectByPrimaryKey(appModel.getBusinessId());
			if (null == browsePermission) {
				throw new RuntimeException("预览申请信息为空!");
			}
			if (!browsePermission.getStatus().equals(BrowseAppStatus.Apploy.getStatus())) {
				throw new RuntimeException("预览申请非提交状态不能提交!");
			}
			// SubApprovalModel nextApprovalUser =
			// getNextAuditUser(appModel.getBusinessId(), appModel.getDepartmentId());
			
			
			List<SubApprovalModel> nextAuditUserList = commonService.getNextAuditUserList(appModel.getBusinessId(),
					appModel.getDepartmentId());
			Map<String, Object> vaiarbles = new HashMap<String, Object>();
			vaiarbles.put("isApproval", true);
			// vaiarbles.put("nextApprovalUser", nextApprovalUser);
			vaiarbles.put("auditUsers", nextAuditUserList);
			vaiarbles.put("processTag", ContractProcessStatus.ApprovalSuccess.getStatus());
			Task task = processEngine.getTaskService().createTaskQuery()
					.processInstanceBusinessKey(appModel.getBusinessId()).singleResult();
			SubApprovalModel subModel = (SubApprovalModel) processEngine.getTaskService().getVariable(task.getId(),
					"subApprovalModel");
			processEngine.getTaskService().setVariableLocal(task.getId(), "browseApprovalSuccessUserInfo",
					nextAuditUserList);

			processEngine.getTaskService().complete(task.getId(), vaiarbles);

			updateContractBrowseStatus(browsePermission, appModel, BrowseAppStatus.Approvaled.getStatus());
			
			//邮件相关
			Contract contract=commonQueryDao.getContractByBrowsePermissionId(appModel.getBusinessId());
			String subject = "【合同查看申请】";
			String emailContent = String.format("您有一个【合同查看申请】【待审批】,合同编号:【%s】 合同名称:【%s】", contract.getContractCode(),
					contract.getContractName());
			String subEmailContent = String.format("您的【合同查看申请】  通过审核! 合同编号:【%s】 合同名称:【%s】", contract.getContractCode(),
					contract.getContractName());
			EmailModel eModel = new EmailModel();
			eModel.setSubject(subject);
			eModel.setActivitiProcessType(ActivitiProcessType.ContactBrowseApprovalProcess);
			eModel.setBussinesOperatorType(ContractProcessStatus.ApprovalSuccess);
			eModel.setCurrentUsers(subModel);
			eModel.setIsSendSubmit(true);
			eModel.setContent(emailContent);
			eModel.setSubmitSubject(subject);
			eModel.setSubContent(subEmailContent);
			eModel.setNextApprovalList(nextAuditUserList);

			emailTaskService.sendEmail(eModel);
		} catch (Exception e) {
			throw e;
		}
	}

	private BrowsePermission getSubitBrowsePersmission(String buinessId) {
		List<BrowsePermission> rBrowsePermissions = commonQueryDao.selectContracBrowsePerssiontByContractId(buinessId);
		if (rBrowsePermissions.size() > 0) {
			return rBrowsePermissions.get(0);
		}
		// java.util.UUID.randomUUID()
		return null;
	}

	/**
	 * 【查看申请流程】 提交申请
	 */
	@Transactional(rollbackFor = Exception.class,isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED)
	@Override
	public void browseAppSubmit(SubApprovalModel appModel) {
		try {
			ValidData(appModel);

			BrowsePermission browsePermission = getSubitBrowsePersmission(appModel.getBusinessId());
			if (null != browsePermission && browsePermission.getStatus().equals(BrowseAppStatus.Apploy.getStatus())) {
				throw new RuntimeException("预览申请已发出，不能再提交!");
			} else {
				browsePermission = new BrowsePermission();
				browsePermission.setContractId(appModel.getBusinessId());
				browsePermission.setReason(appModel.getReason());
				browsePermission.setUserId(appModel.getUserId());
				browsePermission.setStatus(BrowseAppStatus.Apploy.getStatus());
				browsePermission.setBrowsePermissionId(GuidUtils.newGuid());
				browsePermission.setInput(new Date());
				browsePermissionDao.insert(browsePermission);
			}
			SubApprovalModel nextApprovalUser = commonService.getNextApprovalUser(appModel.getBusinessId(),
					appModel.getDepartmentId());
			appModel=commonService.additionalUsers(appModel);
			
			Map<String, Object> vaiarbles = new HashMap<String, Object>();
			vaiarbles.put("subApprovalModel", appModel);
			// vaiarbles.put("isNew", true);
			vaiarbles.put("nextApprovalUser", nextApprovalUser);
			vaiarbles.put("processTag", ContractProcessStatus.Submit.getStatus());
			processEngine.getRuntimeService().startProcessInstanceByKey(browseContractProcessInstanceKey,
					browsePermission.getBrowsePermissionId(), vaiarbles);

			List<SubApprovalModel> nextApprovalList = new ArrayList<>();
			nextApprovalList.add(nextApprovalUser);
			Contract contract=contractDao.selectByPrimaryKey(appModel.getBusinessId());
			String emailContent = String.format("您有一个合同查看申请【待审批】,合同编号:【%s】 合同名称:【%s】", contract.getContractCode(),
					contract.getContractName());
			EmailModel eModel = new EmailModel();
			eModel.setSubject("【合同查看申请】");
			eModel.setActivitiProcessType(ActivitiProcessType.ContactBrowseApprovalProcess);
			eModel.setBussinesOperatorType(ContractProcessStatus.Submit);
			eModel.setCurrentUsers(appModel);
			eModel.setIsSendSubmit(false);
			eModel.setContent(emailContent);
			eModel.setNextApprovalList(nextApprovalList);

			emailTaskService.sendEmail(eModel);
			
		} catch (Exception e) {
			throw e;
		}
	}

	void addBrowseApp(SubApprovalModel appModel) {
		BrowsePermission browsePermission = new BrowsePermission();
		browsePermission.setContractId(appModel.getBusinessId());
		browsePermission.setReason(appModel.getReason());
		browsePermission.setUserId(appModel.getUserId());
		browsePermission.setStatus(BrowseAppStatus.Apploy.getStatus());
		browsePermissionDao.insert(browsePermission);
	}

	private void updateContractBrowseStatus(BrowsePermission browsePermission, SubApprovalModel subModel,
			Short status) {
		// 审核通过修正查看日期范围
		if (status.equals(BrowseAppStatus.Audit.getStatus())) {
			browsePermission.setStart(new Date());
			Calendar calendar = Calendar.getInstance();
			calendar.add(Calendar.DAY_OF_MONTH, 1);
			browsePermission.setEnd(calendar.getTime());
		}
		browsePermission.setStatus(status);
		browsePermissionDao.updateByPrimaryKey(browsePermission);
	}

	private void ValidData(SubApprovalModel appModel) {
		if (null == appModel) {
			throw new RuntimeException("提交Model为空!");
		}
		if (StringUtils.isBlank(appModel.getBusinessId())) {
			throw new RuntimeException("业务Id为空!");
		}
		if (StringUtils.isBlank(appModel.getUserId())) {
			throw new RuntimeException("提交UserId为空!");
		}
		if (StringUtils.isBlank(appModel.getDepartmentId())) {
			throw new RuntimeException("提交DepartmentId为空!");
		}

	}
}
